var PLAYER_TYPE_HUMAN = new PlayerType('h', 'Human'), PLAYER_TYPE_COMPUTER = new PlayerType('c', 'Computer'), pt = [PLAYER_TYPE_HUMAN, PLAYER_TYPE_COMPUTER];
var LINE_TYPE_VERTICAL = new LineType('v', 'Vertical'), LINE_TYPE_HORIZONTAL = new LineType('h', 'Horizontal');
function Line(x, y, t) {
	this.x = x;
	this.y = y;
	this.t = t;
}
function LineType(id, value) {
	this.id = id;
	this.value = value;
}
function Player(id, name, type, color) {
	this.id = id;
	this.name = name;
	this.type = type;
	this.color = color;
	this.score = 0;
	this.turnBegin = function() {
		document.getElementById('sbe' + id).setAttribute('style', 'color:' + color + ';font-weight:bold');
	};
	this.play = function(hl, vl) {
		
	};
	this.increaseScore = function() {
		this.score++;
		var score = document.getElementById('score' + id);
		score.removeChild(score.lastChild);
		score.appendChild(document.createTextNode(this.score));
	};
	this.turnEnd = function() {
		document.getElementById('sbe' + id).setAttribute('style', 'color:' + color);
	};
	this.inputHTML = function() {
		var player = document.createElement('li');
		player.setAttribute('id', 'player' + id);
		var playerName = document.createElement('input');
		playerName.setAttribute('type', 'text');
		playerName.setAttribute('id', 'player' + id + 'name');
		playerName.setAttribute('value', name);
		player.appendChild(playerName);
		var playerType = document.createElement('select');
		playerType.setAttribute('id', 'player' + id + 'type');
		for(var i = 0; i < pt.length; i++) {
			var option = document.createElement('option');
			option.setAttribute('value', pt[i].id);
			var text = document.createTextNode(pt[i].value);
			option.appendChild(text);
			playerType.appendChild(option);
		}
		player.appendChild(playerType);
		var colorSel = document.getElementById('dummy').cloneNode(true);
		colorSel.setAttribute('style', 'background-color: ' + color);
		player.appendChild(colorSel);
		var removePlayer = document.createElement('a');
		removePlayer.setAttribute('href', '#');
		removePlayer.setAttribute('onclick', 'removePlayer(' + id + ');');
		var text = document.createTextNode('X');
		removePlayer.appendChild(text);
		player.appendChild(removePlayer);
		return player;
	};
	this.scoreHTML = function() {
		var tr = document.createElement('tr');
		tr.setAttribute('id', 'sbe' + id);
		tr.setAttribute('style', 'color:' + color);
		var tdName = document.createElement('td');
		tdName.appendChild(document.createTextNode(name));
		tr.appendChild(tdName);
		var tdValue = document.createElement('td');
		tdValue.setAttribute('id', 'score' + id);
		tdValue.setAttribute('align', 'right');
		tdValue.appendChild(document.createTextNode(this.score));
		tr.appendChild(tdValue);
		return tr;
	};
}
function PlayerType(id, value) {
	this.id = id;
	this.value = value;
}
// nr, nc - number of rows and columns of squares
// p - players
function Game(nr, nc, p, view, scoreboard) {
	this.nr = nr;
	this.nc = nc;
	this.p = p;
	this.view = view;
	this.scoreboard = scoreboard;
	// thickness of line
	this.lt = 6;
	// r - radius of the dots
	this.r = this.lt / 2;
	// thickness of the gap between line and inner filled square
	this.gt = 6;
	// inner filled square starting point deviation
	this.sd = this.lt / 2 + this.gt;
	while(scoreboard.lastChild)
		scoreboard.removeChild(scoreboard.lastChild);
	for(var i = 0; i < p.length; i++)
		scoreboard.appendChild(p[i].scoreHTML());
	// vl - vertical lines
	this.vl = [];
	for(var i = 0; i < nr; i++) {
		this.vl[i] = [];
		for(var j = 0; j <= nc; j++)
			this.vl[i][j] = -1;
	}
	// hl - horizontal lines
	this.hl = [];
	for(var i = 0; i <= nr; i++) {
		this.hl[i] = [];
		for(var j = 0; j < nc; j++)
			this.hl[i][j] = -1;
	}
	// nl = number of lines marked so far
	this.nl = 0;
	// g - player who completed each square in grid
	this.g = [];
	for(var i = 0; i < nr; i++) {
		this.g[i] = [];
		for(var j = 0; j < nc; j++) {
			this.g[i][j] = -1;
		}
	}
	// cp - current player
	this.cp = 0;
	this.p[this.cp].turnBegin();
	this.drawDots = function() {
		for(var i = 0; i <= this.nr; i++) {
			for(var j = 0; j <= this.nc; j++) {
				this.view.circle(i + 0.5, j + 0.5, this.r);
			}
		}
	};
	this.end = function() {
		view.removeEventListener(this.handlemouseup);
	};
	this.draw = function() {
		this.view.setHeight(this.nr + 1);
		this.view.setWidth(this.nc + 1);
		this.drawDots();
		for(var i = 0; i < this.nr; i++) {
			for(var j = 0; j <= this.nc; j++)
				if(this.vl[i][j] >= 0)
					this.view.vline(j + 0.5, i + 0.5, 1, this.p[this.vl[i][j]].color, this.lt);
		}
		for(var i = 0; i <= this.nr; i++) {
			for(var j = 0; j < this.nc; j++)
				if(this.hl[i][j] >= 0)
					this.view.hline(j + 0.5, i + 0.5, 1, this.p[this.hl[i][j]].color, this.lt);
		}
		for(var i = 0; i < this.nr; i++) {
			for(var j = 0; j < this.nc; j++) {
				if(this.g[i][j] >= 0)
					this.view.square(j + 0.5, i + 0.5, 1, this.p[this.g[i][j]].color, this.sd);
			}
		}
	};
	this.redraw = function() {
		this.view.clear();
		this.draw();
	};
	this.redraw();
	this.check = function(x, y) {
		var thisObj = game;
		var d1 = x >= 0 && x < thisObj.nc && y >= 0 && y < thisObj.nr && thisObj.hl[y][x] >= 0 && thisObj.hl[y + 1][x] >= 0 && thisObj.vl[y][x] >= 0 && thisObj.vl[y][x + 1] >= 0;
		if(d1) {
			thisObj.p[thisObj.cp].increaseScore();
			thisObj.g[y][x] = thisObj.cp;
			thisObj.view.square(x + 0.5, y + 0.5, 1, thisObj.p[thisObj.cp].color, this.sd);
		}
		return d1;
	};
	this.handlemouseup = function(loc) {
		var thisObj = game;
		if(thisObj.p[thisObj.cp].type != PLAYER_TYPE_HUMAN) {
			alert('Wait for your turn');
			return;
		}
		var x = loc.x - 0.5, y = loc.y - 0.5;
		var fx = Math.floor(x), cx = fx + 1, fy = Math.floor(y), cy = fy + 1;
		var dfx = x - fx, dfy = y - fy, dcx = cx - x, dcy = cy - y, d1 = false;
		if(dfy <= dcy && dfy <= dfx && dfy <= dcx) {
			// base horizontal line
			if(fx < 0 || cx > thisObj.nc || thisObj.hl[fy][fx] >= 0)
				return;
			thisObj.hl[fy][fx] = thisObj.cp;
			thisObj.view.hline(fx + 0.5, fy + 0.5, 1, thisObj.p[thisObj.cp].color, thisObj.lt);
			d1 = thisObj.check(fx, fy - 1);
		} else if(dfx <= dcx && dfx <= dfy && dfx <= dcy) {
			// base vertical line
			if(thisObj.vl[fy][fx] >= 0)
				return;
			thisObj.vl[fy][fx] = thisObj.cp;
			thisObj.view.vline(fx + 0.5, fy + 0.5, 1, thisObj.p[thisObj.cp].color, thisObj.lt);
			d1 = thisObj.check(fx - 1, fy);
		} else if(dcx <= dfx && dcx <= dfy && dcx <= dcy) {
			// next vertical line
			if(thisObj.vl[fy][cx] >= 0)
				return;
			thisObj.vl[fy][cx] = thisObj.cp;
			thisObj.view.vline(cx + 0.5, fy + 0.5, 1, thisObj.p[thisObj.cp].color, thisObj.lt);
			d1 = thisObj.check(cx, fy);
		} else if(dcy <= dfy && dcy <= dfx && dcy <= dcx) {
			// next horizontal line
			if(fx < 0 || cx > thisObj.nc || thisObj.hl[cy][fx] >= 0)
				return;
			thisObj.hl[cy][fx] = thisObj.cp;
			thisObj.view.hline(fx + 0.5, cy + 0.5, 1, thisObj.p[thisObj.cp].color, thisObj.lt);
			d1 = thisObj.check(fx, cy);
		}
		var d2 = thisObj.check(fx, fy);
		if(!d1 && !d2)
			thisObj.switchPlayer();
		thisObj.nl++;
	};
	this.switchPlayer = function() {
		var thisObj = game;
		thisObj.p[thisObj.cp].turnEnd();
		thisObj.cp = (thisObj.cp + 1) % thisObj.p.length;
		thisObj.p[thisObj.cp].turnBegin();
	};
	this.view.addEventListener('mouseup', this.handlemouseup);
}